﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace winformApplication
{
    public class Caculator
    {      
        /// <summary>
        /// 运算符
        /// </summary>
        private static Regex regex = new Regex("[\\+\\-\\*\\/\\^\\$]{1}", RegexOptions.IgnoreCase);

        /// <summary>
        /// 计算表达式的值
        /// </summary>
        /// <param name="expression">算术表达式</param>
        /// <returns></returns>
        public static double caculate(string expression)
        {

            Stack<double> operations = new Stack<double>();
            Stack<string> operators = new Stack<string>();

            string tmpExp = expression + "$";//表达式结束符
            StringBuilder build = new StringBuilder();           
            for (int i=0; i< tmpExp.Length; i++)
            {
                string ch = "" + tmpExp[i];
                //扫描遇到操作符
                if (regex.IsMatch(ch))
                {
                    string operationStr = build.ToString().Trim();
                    double operation = Double.Parse(operationStr);
                    operations.Push(operation);
                    build.Clear();

                    if (operators.Count() > 0)
                    {
                        string op = operators.Pop();
                        double opB = operations.Pop();
                        double opA = operations.Pop();
                        OperationContext context = new OperationContext(opA, opB, op);
                        double result = context.getResult();
                        operations.Push(result);
                    }

                    if(!"$".Equals(ch))
                    {
                        operators.Push(ch);
                    }
                    
                }         
                //操作数      
                else
                {
                    build.Append(ch);
                }
            }

            return operations.Pop();
            
        }

    }
}
